#include "common/elements/edge.h"
#include "common/elements/field_type.h"
#include "common/elements/item.h"
#include "common/elements/item_field.h"
#include "common/elements/item_history.h"
#include "common/elements/item_type.h"
#include "common/elements/item_user_state.h"
#include "common/elements/phase.h"
#include "common/elements/project.h"
#include "common/elements/role.h"
#include "common/elements/role_menu_item.h"
#include "common/elements/rule.h"
#include "common/elements/rule_item_type.h"
#include "common/elements/rule_project.h"
#include "common/elements/rule_state.h"
#include "common/elements/state.h"
#include "common/elements/team.h"
#include "common/elements/user.h"
#include "common/elements/user_team_role.h"
#include "common/elements/workflow.h"

#include "element_maker.h"
#include "item_field.h"

namespace Elements
{

Element* fromJsonString(const std::string& jsonValue)
{
    return fromJson(nlohmann::json::parse(jsonValue));
}

Element* fromJson(const Common::Json& json)
{
    const auto elementType = ElementType(json["elementType"].get<unsigned>());

    Element* result = nullptr;
    switch (elementType)
    {
    case ElementType::None:
        break;
    case ElementType::Item:
        result = new Item();
        break;
    case ElementType::ItemType:
        result = new ItemType();
        break;
    case ElementType::FieldType:
        result = new FieldType();
        break;
    case ElementType::Workflow:
        result = new Workflow();
        break;
    case ElementType::State:
        result = new State();
        break;
    case ElementType::Edge:
        result = new Edge();
        break;
    case ElementType::User:
        result = new User();
        break;
    case ElementType::Role:
        result = new Role();
        break;
    case ElementType::Team:
        result = new Team();
        break;
    case ElementType::UserTeamRole:
        result = new UserTeamRole();
        break;
    case ElementType::RoleMenuItem:
        result = new RoleMenuItem();
        break;
    case ElementType::Rule:
        result = new Rule();
        break;
    case ElementType::RuleState:
        result = new RuleState();
        break;
    case ElementType::RuleItemType:
        result = new RuleItemType();
        break;
    case ElementType::RuleProject:
        result = new RuleProject();
        break;
    case ElementType::Project:
        result = new Project();
        break;
    case ElementType::Phase:
        result = new Phase();
        break;
    case ElementType::ItemHistory:
        result = new ItemHistory();
        break;
    case ElementType::ItemUserState:
        result = new ItemUserState();
        break;
    case ElementType::ItemField:
        result = new ItemField();
        break;
    }
    result->fromJson(json);
    return result;
}

} // namespace Elements
